import cv2 as cv
import numpy as np
import math

#对矩形的计算
def Calculation(box):
    #求最小矩形各个顶点坐标
    left_point_x = np.min(box[:, 0])
    right_point_x = np.max(box[:, 0])
    bottom_point_y = np.max(box[:, 1])
    left_point_y = box[:, 1][np.where(box[:, 0] == left_point_x)][0]
    right_point_y = box[:, 1][np.where(box[:, 0] == right_point_x)][0]
    bottom_point_x = box[:, 0][np.where(box[:, 1] == bottom_point_y)][0]
    #计算矩形长宽
    W = math.sqrt((right_point_x - bottom_point_x)**2 + (right_point_y - bottom_point_y)**2)
    H = math.sqrt((bottom_point_x - left_point_x)**2 + (left_point_y - bottom_point_y)**2)
    
    return W,H
#检测目标轮廓
def findContours(img,U,L,B):
    #将图像转到HSV色彩空间
    hsv_img = cv.cvtColor(img, cv.COLOR_BGR2HSV)

    #不同颜色的不同HSV参数
    #蓝色
    #low_light = np.array([50, 43, 200])
    #high_light = np.array([130, 255, 255])

    #橙黄色
    low_light = np.array([11, 43, 46])
    high_light = np.array([34, 255, 255])

    #白色
    #low_light = np.array([0, 0, 221])
    #high_light = np.array([180, 43, 255])

    #根据HSV范围对图像二值化
    mask = cv.inRange(hsv_img, low_light, high_light)
    #寻找轮廓
    contours,hierarchy = cv.findContours(mask, cv.RETR_LIST, cv.CHAIN_APPROX_SIMPLE)
    
    i = 0
    Rec = []#储存矩形坐标
    WH = []#储存矩形长宽及编号

    for cnt in contours:
        minR = cv.minAreaRect(cnt)
        Box = cv.boxPoints(minR)
        Box = np.int0(Box)#
        w=h=0
        #计算获得矩形长宽
        w,h = Calculation(Box)
        
        if w == 0 or h == 0:
            continue
        #最小面积
        elif  w*h <= B:
            continue
        #长宽比
        elif w/h <= U and w/h >= L:
            Rec.append(Box)
            WH.append([w,h,i])
            i = i+1
        elif h/w <= U and h/w >= L:
            Rec.append(Box)
            WH.append([w,h,i])
            i = i+1
    #根据矩形面积大小排序
    WH = sorted(WH, key=lambda a: a[0]*a[1], reverse=True)

    Final_Box = []#储存最终通过筛选的轮廓角点坐标
    
    t = 0
    for b in WH:
        arr = Rec[b[2]]#从Rec列表中提取对应编号i的轮廓
        Final_Box.append(arr.tolist())#将numpy数组转化为列表并添加到Final_Box中
        t=t+1
        #当检测完前两个轮廓后跳出循环
        if t == 2:
            break
    
    return Final_Box,i